package configuration;

import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.SAXException;

import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class Configuration {
    private static Configuration sgl = null;
    private HashMap<String,String> options = null;
    private Configuration(){}
    
    public static Configuration getInstance() {
        if (sgl == null) {
            sgl = new Configuration();
            try {
                sgl.parse();
            } catch (Exception ex) {
                System.out.println("Configuration init:" + ex.toString());
            }
        }
        return sgl;
    }
    
    public void parse() throws Exception {
        // 将我们的解析器对象化
        ConfigParser handler = new ConfigParser();

        // 获取SAX工厂对象
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(false);
        factory.setValidating(false);

        // 获取SAX解析
        SAXParser parser = factory.newSAXParser();

        try {
            // 将解析器和解析对象myenv.xml联系起来,开始解析
            parser.parse("config\\conf.xml", handler);
            // 获取解析成功后的属性 以后 我们其他应用程序只要调用本程序的props就可以提取出属性名称和值了
            options = handler.getOptions();
            // props = handler.getProps();
        } finally {
            factory = null;
            parser = null;
            handler = null;
        }
    }
    
    public String getOption(String opt) {
        if (options.containsKey(opt)) {
            return options.get(opt);
        }
        return null;
    }

    public static void main(String args[]) {
        Configuration conf = new Configuration();
        try {
            conf.parse();
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
        System.out.println(conf.getOption("SiteConfiguration.default.dataport"));
    }
}

class ConfigParser extends DefaultHandler {
    private ArrayList<String> path = new ArrayList<String>();
    private HashMap<String,String> options = new HashMap<String, String>();

    public HashMap<String,String> getOptions() {
        return options;
    }
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        path.add(qName);
        //System.out.println(uri + " " + localName + " " + qName);
    }

    public void characters(char[] ch, int start, int length)
            throws SAXException {
        int cursor = start;
        int end = start + length;
        while ((ch[cursor] == ' ' || ch[cursor] == '\n' || ch[cursor] == '\r') && cursor < start + length)
            cursor ++;
        if (cursor == start + length)
            return;
        start =cursor;
        cursor = end - 1;
        while ((ch[cursor] == ' ' || ch[cursor] == '\n' || ch[cursor] == '\r') && cursor > start)
            cursor --;
        length = cursor - start + 1;
        String val = new String(ch,start,length);
        StringBuffer currentVal = new StringBuffer();
        for (int i = 0; i < path.size(); i ++) {
            currentVal.append(path.get(i));
            if (i != path.size()-1)
                currentVal.append('.');
        }
        options.put(currentVal.toString(), val);
        System.out.println(currentVal + ":" + val);
    }

    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        path.remove(path.size() - 1);
        //System.out.println(uri + " " + localName + " " + qName);
    }
}